package com.duoduo.commonn.redis.factory;


import com.duoduo.common.api.constants.Constant;
import com.duoduo.common.api.constants.LogConstant;
import com.duoduo.common.api.help.DynamicProxyInnerUtil;
import com.duoduo.common.api.help.SpringContextInnerUtil;
import com.duoduo.common.api.myinterface.CacheOperator;
import com.duoduo.common.api.myinterface.tracer.RedisTracer;
import com.duoduo.common.api.spi.extension.ExtensionLoader;
import com.duoduo.commonn.redis.handle.TraceHandler;
import com.duoduo.commonn.redis.myinterface.RedisOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Map;

public class RedisCacheFactory implements CacheOperator {
	
	private static final Logger logger = LoggerFactory.getLogger(RedisCacheFactory.class);
	private RedisOperator redisOperator;

	public RedisCacheFactory(){
		//缓存默认使用redis实现，redis默认使用jedis操作
		String redisImplType = SpringContextInnerUtil.get(Constant.REDIS_IMPL);
		logger.info(LogConstant.REDIS_CACHE + " impl type: {}", redisImplType);
		// 如果有链路跟踪
		if(SpringContextInnerUtil.containsBean(Constant.TRACER_BEANNAME)){
			RedisOperator proxy = ExtensionLoader.getExtensionLoader(RedisOperator.class).getExtension(redisImplType);
			RedisTracer tracer = ExtensionLoader.getExtensionLoader(RedisTracer.class).getExtension(Constant.TRACER_REDIS_CLIENT_NAME);
			redisOperator = DynamicProxyInnerUtil.getProxy(proxy, new TraceHandler<RedisOperator>(tracer));
		}else{
			redisOperator = ExtensionLoader.getExtensionLoader(RedisOperator.class).getExtension(redisImplType);
		}
	}

	@Override
	public String get(String prefixName, String appName, String key) {
		return redisOperator.get(prefixName, appName, key);
	}

	@Override
	public <T extends Serializable> T getObjImplSeri(String prefixName, String appName, String key, Class<T> clazz) {
		return redisOperator.getObjImplSeri(prefixName, appName, key, clazz);
	}

	@Override
	public Long delKey(String prefixName, String appName, String key) {
		return redisOperator.delKey(prefixName, appName, key);
	}
	
	@Override
	public String set(String prefixName, String appName, String key, String value, int expire) {
		return redisOperator.set(prefixName, appName, key, value, expire);
	}

	@Override
	public <T extends Serializable> String setImplSeri(String prefixName, String appName, String key, T value, int expire) {
		return redisOperator.setImplSeri(prefixName, appName, key, value, expire);
	}
	
	@Override
	public long incr(String prefixName, String appName, String key) {
		return redisOperator.incr(prefixName, appName, key);
	}
	
	@Override
	public long decr(String prefixName, String appName, String key) {
		return redisOperator.decr(prefixName, appName, key);
	}
	
	@Override
	public Boolean exists(String prefixName, String appName, String key) {
		return redisOperator.exists(prefixName, appName, key);
	}

	@Override
	public Boolean existsSeri(String prefixName, String appName, String key) {
		return redisOperator.existsSeri(prefixName, appName, key);
	}
	
	@Override
	public Long hincrBy(String prefixName, String appName, String key, String field, Long value) {
		return redisOperator.hincrBy(prefixName, appName, key, field, value);
	}

	@Override
	public Long hashSet(String prefixName, String appName, String key, String field, String value) {
		return redisOperator.hashSet(prefixName, appName, key, field, value);
	}

	@Override
	public Long hashSet(String prefixName, String appName, String key, String field, String value, int expire) {
		return redisOperator.hashSet(prefixName, appName, key, field, value, expire);
	}

	@Override
	public <T extends Serializable> Long hashSetImplSeri(String prefixName, String appName, String key, String field, T value) {
		return redisOperator.hashSetImplSeri(prefixName, appName, key, field, value);
	}

	@Override
	public <T extends Serializable> Long hashSetImplSeri(String prefixName, String appName, String key, String field, T value, int expire) {
		return redisOperator.hashSetImplSeri(prefixName, appName, key, field, value, expire);
	}

	@Override
	public String hashGet(String prefixName, String appName, String key, String field) {
		return redisOperator.hashGet(prefixName, appName, key, field);
	}

	@Override
	public <T extends Serializable> T hashGetImplSeri(String prefixName, String appName, String key, String field, Class<T> clazz) {
		return redisOperator.hashGetImplSeri(prefixName, appName, key, field, clazz);
	}

	@Override
	public Map<String, String> hashGetAll(String prefixName, String appName, String key) {
		return redisOperator.hashGetAll(prefixName, appName, key);
	}

	@Override
	public <T extends Serializable> Map<String, T> hashGetAllImplSeri(String prefixName, String appName, String key, Class<T> clazz) {
		return redisOperator.hashGetAllImplSeri(prefixName, appName, key, clazz);
	}

	@Override
	public Long listPushTail(String prefixName, String appName, String key, String... values) {
		return redisOperator.listPushTail(prefixName, appName, key, values);
	}

	@Override
	public Long listPushHead(String prefixName, String appName, String key, String... values) {
		return redisOperator.listPushHead(prefixName, appName, key, values);
	}

	@Override
	public String listPop(String prefixName, String appName, String key) {
		return redisOperator.listPop(prefixName, appName, key);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends Serializable> Long listPushTailImplSeri(String prefixName, String appName, String key, T... values) {
		return redisOperator.listPushTailImplSeri(prefixName, appName, key, values);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends Serializable> Long listPushHeadImplSeri(String prefixName, String appName, String key, T... values) {
		return redisOperator.listPushHeadImplSeri(prefixName, appName, key, values);
	}

	@Override
	public <T extends Serializable> T listPopImplSeri(String prefixName, String appName, String key, Class<T> clazz) {
		return redisOperator.listPopImplSeri(prefixName, appName, key, clazz);
	}

}